package com.面试题;

public class String的常量与变量问题 {
    public static void main(String[] args) {


         /*
        String对象是不可变的,每次改变字符串对象实际上是新产生的字符串对象了,以"abc"方式写出的字符串,会在堆内存中的字符串常量池中存储,且相同内容的字符串只存储一份,目的是节约内存;但是通过new方式创建的字符串对象,每new一次都会产生一个新的对象放在堆内存中
        */

        String s1, s2;
        //如果使用
        s1 = "S";
        s2 = "S";
        System.out.println(s1 == s2);
        //会发现结果始终为true,这是由于java的字符串常量复用造成的,s1 s2 指向同一个地址
        System.out.println(s1.equals(s2));//因为二者就是同一个字符串常量,所以始终为true
        System.out.println("+-+-+-+-+-+-+-+-+");
//笔试题1
        s2 = new String("abc");//这一行就在堆中产生了两个对象,其中一个在堆内存常量池中
        s1 = "abc";//因为常量池中已经有"abc"了,所以不会再创建对象
        System.out.println(s1 == s2);//由于s1 s2指向不同的对象(都在堆内存中,但是一个"abc"在常量池中,一个在常量池外)所以false
        System.out.println("+-+-+-+-+-+-+-+-+");
//笔试题2
        s1 = "abc";//"abc"加入常量池
        s2 = "ab";//"ab"加入常量池
        String s3 = s2 + "c";//"c"加入常量池,同时运算拼成新的字符串会在堆内存中常量池外生成新的对象的,与常量池中已经存在的"abc"无关
        System.out.println(s1 == s3);//false
        System.out.println("+-+-+-+-+-+-+-+-+");
//笔试题3
        s1 = "abc";//在常量池中生成"abc"
        s2 = "a" + "b" + "c";//在常量池中生成"a" "b" "c" "ab" "abc" 尽管是运算拼成的"abc"但是存在常量优化机制,因为运算不涉及变量,所以编译器会把"a"+"b"+"c"直接转成"abc",因此使用的是常量池中已经存在的"abc"
        System.out.println(s1 == s2);//true
        System.out.println("+-+-+-+-+-+-+-+-+");


        String str1 = "abc";
        String str = "abc";
        String str2 = new String("abc");
        System.out.println(str1 == str2);//false
        System.out.println(str1.equals(str2));//true
        System.out.println(str == str1);//true
    }
}
